package com.weicong.library;

import android.content.Context;
import android.os.Handler;
import android.support.annotation.DrawableRes;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import java.util.ArrayList;

public class ImageCycleView extends RelativeLayout {

    /**
     * 水平居中
     */
    public static final int CENTER = 0;

    /**
     * 居右
     */
    public static final int RIGHT = 1;

    /**
     * 可循环的ViewPager
     */
    private CycleViewPager mCycleViewPager;

    /**
     * CycleViewPager的adapter
     */
    private PagerAdapter mPagerAdapter;

    /**
     * 两个指示符之间的间隔，默认值为5
     */
    private int mIndicatorMargin = 5;

    /**
     * 存放图片轮播指示器容器
     */
    private LinearLayout mIndicatorLayout;

    /**
     * 滚动图片指示器视图列表
     */
    private ImageView[] mImageIndicators;

    /**
     * 手机密度
     */
    private float mDensity;

    /**
     * 指示器离底部的边距，默认值为10
     */
    private int mBottomMargin = 10;

    /**
     * 指示器离右边的边距（当指示器居右时可用），默认值为12，
     */
    private int mRightMargin = 12;

    /**
     * 指示器的位置
     */
    private int mIndicatorPos = CENTER;

    /**
     * 当前选中显示的指示符的资源id
     */
    private int mIndicatorSelect = R.drawable.indicator_select;

    /**
     * 普通指示符的资源id
     */
    private int mIndicatorNormal = R.drawable.indicator_normal;

    /**
     * 图片占位符，用于请求Url图片
     */
    private int mPlaceHolder = R.drawable.placeholder;

    /**
     * 图片滚动当前图片的下标
     */
    private int mImageIndex = 0;

    /**
     * 标记是否已经设置了图片
     */
    private boolean mIsSetImage = false;

    /**
     * 是否开始自动轮循
     */
    private boolean mRun = false;

    /**
     * 图片滚动的间隔，默认为5秒
     */
    private int mTime = 5000;

    /**
     * 用于处理自动切换图片
     */
    private Handler mHandler = new Handler();

    /**
     * 图片自动轮播Task
     */
    private Runnable mImageTimerTask = new Runnable() {

        @Override
        public void run() {
            if (mImageIndicators != null) {
                int next = (mImageIndex+1) % (mImageIndicators.length+1);
                mCycleViewPager.setCurrentItem(next);
            }
        }
    };

    /**
     * Item单击监听器
     */
    private OnItemClickListener mListener;

    public ImageCycleView(Context context) {
        this(context, null);
    }

    public ImageCycleView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ImageCycleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    /**
     * 初始化
     */
    private void init() {

        mDensity = getResources().getDisplayMetrics().density;
        mCycleViewPager = new CycleViewPager(getContext());
        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT);
        addView(mCycleViewPager, params);
        initIndicatorLayout();
    }

    /**
     * 初始化指示器容器
     */
    private void initIndicatorLayout() {
        if (mIndicatorLayout != null) {
            removeView(mIndicatorLayout);
        } else {
            mIndicatorLayout = new LinearLayout(getContext());
            mIndicatorLayout.setOrientation(LinearLayout.HORIZONTAL);
        }
        LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT);
        params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);

        if (mIndicatorPos == RIGHT) {
            params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
            params.setMargins(0, 0, (int)(mRightMargin * mDensity),
                    (int)(mBottomMargin * mDensity));
        } else {
            params.addRule(RelativeLayout.CENTER_HORIZONTAL);
            params.setMargins(0, 0, 0, (int)(mBottomMargin * mDensity));
        }
        addView(mIndicatorLayout, params);
    }

    /**
     * 初始化指示器
     * @param size 指示器的多少
     */
    private void initIndicators(int size) {
        mIndicatorLayout.removeAllViews();
        mImageIndicators = new ImageView[size];
        LinearLayout.LayoutParams params;
        if (mImageIndex >= size) {
            mImageIndex = 0;
        }
        for (int i = 0; i < size; i++) {
            mImageIndicators[i] = new ImageView(getContext());
            params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
                    LayoutParams.WRAP_CONTENT);
            params.setMargins(mIndicatorMargin, 0, mIndicatorMargin, 0);
            mImageIndicators[i].setLayoutParams(params);
            if (i == mImageIndex) {
                mImageIndicators[i].setImageResource(mIndicatorSelect);
            } else {
                mImageIndicators[i].setImageResource(mIndicatorNormal);
            }
            mIndicatorLayout.addView(mImageIndicators[i]);
        }
    }

    /**
     * 设置图片的id集合
     * @param imageRes 图片id集合
     */
    public void setImageRes(ArrayList<Integer> imageRes) {
        initIndicators(imageRes.size());
        mPagerAdapter = new ImageResAdapter(getContext(), imageRes, mListener);
        setAdapter();
    }

    /**
     * 设置图片的Url集合
     * @param imageUrls 图片Url集合
     */
    public void setImageUrl(ArrayList<String> imageUrls) {
        initIndicators(imageUrls.size());
        mPagerAdapter = new ImageUrlAdapter(getContext(), imageUrls,
                mPlaceHolder, mListener);
        setAdapter();
    }

    /**
     * 设置adapter
     */
    private void setAdapter() {
        mCycleViewPager.setAdapter(mPagerAdapter);
        mCycleViewPager.setCurrentItem(mImageIndex);
        mCycleViewPager.setOnPageChangeListener(new MyPageChangeListener());
        mIsSetImage = true;
    }

    /**
     * 设置配置Config
     * @param config Config对象
     */
    public void setConfig(Config config) {
        if (mIsSetImage) {
            throw new RuntimeException("必须在setImageRes或setImageUrl方法前调用");
        } else if (mRun) {
            throw new RuntimeException("必须在start方法前调用");
        }
        config.apply(this);
    }

    /**
     * 开始图片滚动任务
     */
    public void start() {
        stop();
        mHandler.postDelayed(mImageTimerTask, mTime);
        mRun = true;
    }

    /**
     * 停止图片滚动任务
     */
    public void stop() {
        mHandler.removeCallbacks(mImageTimerTask);
        mRun = false;
    }

    /**
     * 配置类
     */
    public static final class Config {

        /**
         * 两个指示符之间的间隔，默认值为5
         */
        private int mIndicatorMargin = 5;

        /**
         * 指示器离底部的边距，默认值为10
         */
        private int mBottomMargin = 10;

        /**
         * 指示器离右边的边距（当指示器居右时可用），默认值为12，
         */
        private int mRightMargin = 12;

        /**
         * 图片滚动的间隔，默认为5秒
         */
        private int mTime = 5000;

        /**
         * 指示器的位置
         */
        private int mIndicatorPos = CENTER;

        /**
         * 当前选中显示的指示符的资源id
         */
        private int mIndicatorSelect = R.drawable.indicator_select;

        /**
         * 普通指示符的资源id
         */
        private int mIndicatorNormal = R.drawable.indicator_normal;

        /**
         * 图片占位符，用于请求Url图片
         */
        private int mPlaceHolder = R.drawable.placeholder;

        /**
         * 默认选中的下标
         */
        private int mCurrentIndex = 0;

        /**
         * Item单击监听器
         */
        private OnItemClickListener mListener;

        /**
         * 设置选中的指示符的资源id
         * @param selectRes 资源id
         * @return Config对象
         */
        public Config setIndicatorSelectRes(@DrawableRes int selectRes) {
            mIndicatorSelect = selectRes;
            return this;
        }

        /**
         * 设置指示符的资源id
         * @param normalRes 资源id
         * @return Config对象
         */
        public Config setIndicatorNormalRes(@DrawableRes int normalRes) {
            mIndicatorNormal = normalRes;
            return this;
        }

        /**
         * 设置图片占位符，用于请求Url图片
         * @param placeHolder 占位符资源id
         * @return Config对象
         */
        public Config setPlaceHolder(@DrawableRes int placeHolder) {
            mPlaceHolder = placeHolder;
            return this;
        }

        /**
         * 设置指示符的位置
         * @param position 位置
         * @return Config对象
         */
        public Config setIndicatorPos(int position) {
            mIndicatorPos = position;
            return this;
        }

        /**
         * 设置图片滚动的间隔
         * @param time 时间，单位为毫秒
         * @return Config对象
         */
        public Config setTime(int time) {
            mTime = time;
            return this;
        }

        /**
         * 设置默认选中的下标
         * @param index 下标
         * @return Config对象
         */
        public Config setCurrentIndex(int index) {
            if (index < 0) {
                index = 0;
            }
            mCurrentIndex = index;
            return this;
        }

        /**
         * 设置item单击监听器
         * @param listener item单击监听器
         * @return Config对象
         */
        public Config setOnItemClickListener(OnItemClickListener listener) {
            mListener = listener;
            return this;
        }

        /**
         * 设置指示器离右边的边距（当指示器居右时可用）
         * @param rightMargin 右边距
         * @return Config对象
         */
        public Config setRightMargin(int rightMargin) {
            mRightMargin = rightMargin;
            return this;
        }

        /**
         * 设置指示器离底部的边距
         * @param bottomMargin 底边距
         * @return Config对象
         */
        public Config setBottomMargin(int bottomMargin) {
            mBottomMargin = bottomMargin;
            return this;
        }

        /**
         * 设置两个指示符之间的间隔
         * @param indicatorMargin 指示符的间隔
         * @return Config对象
         */
        public Config setIndicatorMargin(int indicatorMargin) {
            mIndicatorMargin = indicatorMargin;
            return this;
        }

        /**
         * 将Config对象应用到ImageCycleView上
         * @param view ImageCycleView对象
         */
        private void apply(ImageCycleView view) {
            view.mIndicatorMargin = this.mIndicatorMargin;
            view.mBottomMargin = this.mBottomMargin;
            view.mRightMargin = this.mRightMargin;
            view.mIndicatorPos = this.mIndicatorPos;
            view.mIndicatorSelect = this.mIndicatorSelect;
            view.mIndicatorNormal = this.mIndicatorNormal;
            view.mImageIndex = this.mCurrentIndex;
            view.mTime = this.mTime;
            view.mPlaceHolder = this.mPlaceHolder;
            view.mListener = this.mListener;
            view.initIndicatorLayout();
        }

    }

    /**
     * 轮播图片状态监听器
     */
    private final class MyPageChangeListener implements ViewPager.OnPageChangeListener {

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            if (mImageIndex != position) {
                mImageIndicators[mImageIndex].setImageResource(mIndicatorNormal);
                mImageIndicators[position].setImageResource(mIndicatorSelect);
                mImageIndex = position;
            }
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            if (state == ViewPager.SCROLL_STATE_DRAGGING) {
                stop();
            } else if (state == ViewPager.SCROLL_STATE_IDLE) {
                start();
            }
        }
    }

    /**
     * 单击Item监听器
     */
    public interface OnItemClickListener {
        void onItemClick(View view, int position);
    }
}
